package com.soup.bytebuddy;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.pool.TypePool;
import net.bytebuddy.utility.JavaModule;

import java.lang.instrument.Instrumentation;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 〈一句话功能简述〉<br>
 *
 * @author 19041060
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class PreMainTraceAgent {

    private final static String targetClassName = ThreadPoolExecutor.class.getName();

    public static void premain(String agentArgs, Instrumentation inst) {

        System.out.println("print pre main");
        /*new AgentBuilder.Default()
                .type(ElementMatchers.named(targetClassName))
                .transform(new AgentBuilder.Transformer() {
                    @Override
                    public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder,
                                                            TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {

                        TypePool typePool = TypePool.Default.ofClassPath();
                        return new ByteBuddy().redefine(typePool.describe("").resolve(), ClassFileLocator.ForClassLoader.ofClassPath())
                                .defineConstructor(Visibility.PUBLIC)
                                .withParameters(Integer.class, Integer.class, Long.class,
                                        TimeUnit.class, BlockingQueue.class, ThreadFactory.class, RejectedExecutionHandler.class)
                                .intercept(FixedValue.value("test"));

                        //return builder.method(ElementMatchers.named("toString"))
                        //        .intercept(FixedValue.value("test"));
                    }
                }).installOn(inst);*/

        // Bytebuddy 的 API 用来修改
        /*AgentBuilder agentBuilder = new AgentBuilder.Default()
                .with(AgentBuilder.PoolStrategy.Default.EXTENDED)
                .with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
                .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
                // .with(new WeaveListener())
                .disableClassFormatChanges();*/
    }

    // 本地启动
    public static void main(String[] args) throws Exception {
        ByteBuddyAgent.install();
        Instrumentation inst = ByteBuddyAgent.getInstrumentation();
        // 增强
        premain(null, inst);

        // 调用
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 5000L,
                TimeUnit.MILLISECONDS, new PriorityBlockingQueue<>(),
                Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        System.out.println(executor.getKeepAliveTime(TimeUnit.MILLISECONDS));
    }
}
